
package com.ruoyi.system.mapper;

import org.springframework.jdbc.core.JdbcTemplate;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PhoneDbManager {
    // 基础数据库连接配置
    private static String baseUrl = "jdbc:mysql://localhost:3306/";
    private static String username = "root";
    private static String password = "123456";
    private static String driverClassName = "com.mysql.cj.jdbc.Driver";

    // 存储手机号对应的JdbcTemplate
    private static final Map<String, JdbcTemplate> phoneDbMap = new HashMap<>();

    /**
     * 初始化基础配置
     */
    public static void initConfig(String baseUrl, String username,
                                  String password, String driverClassName) {
        PhoneDbManager.baseUrl = baseUrl;
        PhoneDbManager.username = username;
        PhoneDbManager.password = password;
        PhoneDbManager.driverClassName = driverClassName;
    }

    /**
     * 获取或创建手机号对应的数据库连接
     */
    public static JdbcTemplate getPhoneDatabase(String phone) {
        // 如果已存在直接返回
        if (phoneDbMap.containsKey(phone)) {
            return phoneDbMap.get(phone);
        }

        // 创建新的连接
        try {
            String dbName = "db_" + phone; // 手机号作为数据库名
            String url = baseUrl + dbName + "?useSSL=false&serverTimezone=UTC";

            // 使用Hikari连接池
            HikariDataSource dataSource = new HikariDataSource();
            dataSource.setDriverClassName(driverClassName);
            dataSource.setJdbcUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            dataSource.setMaximumPoolSize(5);
            dataSource.setMinimumIdle(1);

            // 测试连接
            Connection conn = dataSource.getConnection();
            conn.close();

            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            phoneDbMap.put(phone, jdbcTemplate);
            return jdbcTemplate;
        } catch (SQLException e) {
            throw new RuntimeException("创建数据库连接失败: " + e.getMessage());
        }
    }

    /**
     * 创建手机号对应的数据库
     */
    public static void createPhoneDatabase(String phone) {
        // 先连接到默认数据库(mysql)
        HikariDataSource adminDataSource = new HikariDataSource();
        adminDataSource.setJdbcUrl(baseUrl + "mysql?useSSL=false");
        adminDataSource.setUsername(username);
        adminDataSource.setPassword(password);

        JdbcTemplate adminTemplate = new JdbcTemplate(adminDataSource);

        try {
            String dbName =  phone;
            // 创建数据库
            adminTemplate.execute("CREATE DATABASE IF NOT EXISTS " + dbName);

            // 创建用户并授权(可选)
            // adminTemplate.execute("CREATE USER IF NOT EXISTS '" + dbName + "'@'%' IDENTIFIED BY '" + password + "'");
            // adminTemplate.execute("GRANT ALL PRIVILEGES ON " + dbName + ".* TO '" + dbName + "'@'%'");

            // 初始化数据库连接
            getPhoneDatabase(phone);
        } finally {
            adminDataSource.close();
        }
    }

    /**
     * 在手机号对应的数据库中执行SQL
     */
    public static List<Map<String, Object>> executeQuery(String phone, String sql) {
        return getPhoneDatabase(phone).queryForList(sql);
    }

    public static int executeUpdate(String phone, String sql) {
        return getPhoneDatabase(phone).update(sql);
    }

    /**
     * 在手机号对应的数据库中创建表
     */
    public static void createTable(String phone, String tableName, String columns) {
        executeUpdate(phone, "CREATE TABLE IF NOT EXISTS " + tableName + " (" + columns + ")");
    }

    /**
     * 检查数据库连接状态
     */
    public static String checkConnection(String phone) {
        try {
            getPhoneDatabase(phone).execute("SELECT 1");
            return "连接正常";
        } catch (Exception e) {
            return "连接异常: " + e.getMessage();
        }
    }

    /**
     * 关闭所有连接
     */
    public static void shutdown() {
        phoneDbMap.values().forEach(template -> {
            DataSource ds = template.getDataSource();
            if (ds instanceof HikariDataSource) {
                ((HikariDataSource) ds).close();
            }
        });
        phoneDbMap.clear();
    }
}